home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / ACCOUTIL / LTSTIPS2.LZH / INSID123.DOC < prev    next >
Text File  |  1985-11-28  |  15KB  |  237 lines

  1.                       Inside 1-2-3 Worksheet Files
  2.              (PC Tech Journal October 1984 by W. F. Sharpe)
  3.  
  4.      For some tasks, 123 requires substantial effort and has an
  5. excessive "run time."  It is difficult to do multiple regression,
  6. quadratic programming, and matrix inversion with 123; these tasks are
  7. more easily performed with other programs.
  8.      Even for such procedures, however, 123 is ideal for preparing
  9. input, transforming variables in various ways, and providing graphs of
  10. output.  Its good points can be used to advantage and its drawbacks
  11. alleviated if 123 is used for preparation of input for a "foreign"
  12. program and for analysis of its output.
  13.      A typical procedure involves five steps:
  14.           1. Prepare input using 123, saving the input as a 123
  15. worksheet file.
  16.           2. Use the Lotus Translate facility to convert the 123
  17. worksheet file to a DIF file.
  18.           3. Run the foreign program, which takes its input from
  19. the DIF input file and sends its output to another DIF file.
  20.           4. Use the Lotus Translate facility to convert the DIF
  21. output file to a 123 worksheet file.
  22.           5. Load the output worksheet file into 123 for further
  23. analysis, plotting, etc.
  24.      This is not simple.  Moreover, since most of the information is
  25. numeric, a great deal of translation is involved.  123 stores numeric
  26. data in binary format.  In the DIF format, numbers are stored as ASCII
  27. characters.  Thus step two translates binary numbers to ASCII character
  28. strings.  The foreign program must retranslate the character strings to
  29. binary numbers, do its work, then translate its numeric output to
  30. character strings to be written in the DIF format.  Step four involves
  31. further translation -- from character strings to binary numbers.  For
  32. large problems, such translation can require minutes of processing.
  33.      There is a better way. An analytic program can read input directly
  34. from a 123 worksheet file and prepare another 123 worksheet file
  35. containing output.  This obviates steps two and four, speeds up the
  36. process and allows more information to be transferred between 123 and
  37. the "foreign" program.
  38.      To write such programs, of course, it is necessary to understand
  39. the format of 123 worksheet files.  Lotus does not currently provide
  40. this information, but it can be deduced by examining enough examples of
  41. files created with 123.
  42.      The following information is believed to be accurate for Version
  43. 1A of Lotus 123 for the IBM PC.  A BASIC program for reading and
  44. printing data from a file is used for illustration.
  45.      Worksheet files are composed of a series of records of variable
  46. lengths.  Each record begins with a header consisting of a pair of
  47. two-byte integers that indicates the record type and length.  The
  48. record length indicates the number of bytes in the remainder of the
  49. record.  There are many types of records.  For reading and writing
  50. files of data, the following suffice:
  51.  
  52.           Record type  0:  Header
  53.           Record type  6:  Range
  54.           Record type 13:  Integer value
  55.           Record type 14:  Double-precision value
  56.           Record type 15:  Character string (Label)
  57.           Record type 16:  Formula and current value
  58.           Record type  1:  End-of-worksheet
  59.  
  60.      The INSIDE.BAS program reads and prints the contents of a worksheet
  61. file.
  62.      To process a worksheet involves: opening the file and checking for
  63. a valid header; reading and processing records; and stopping when the
  64. end-of-worksheet record has been read.  Lines 40 through 100 of the
  65. program provide a "main routine" to do this.  Two routines are called
  66. -- one (line 120) to open the file, and another (line 210) to read and
  67. process a record.
  68.      Worksheet files may contain anything -- including a Control-Z
  69. (ASCII 26) character.  Since this signals the end of a standard text
  70. file, "random" file access must be used, even for serial processing.
  71. In BASIC, random files may have no more than 32,767 records.  Since
  72. worksheet files can be long, a relatively large record size is
  73. necessary.
  74.      The sample program uses records of 128 characters.  Portions of
  75. the file are read into a character string called BUFFER$, as needed.
  76. The procedure to do this extends from lines 120 through 190.  Lines
  77. 130-160 receive the name of the file from the user, append .WKS, open
  78. it as a random file with a record length of 128 and assign all input to
  79. a 128-character string named BUFFER$.  Line 170 reads the first 128
  80. characters into BUFFER$.  Line 180 sets POINTER% to indicate that the
  81. next available byte is the first character in BUFFER$.  Line 190
  82. returns to the calling procedure (in this case, the main routine).
  83.      The workhorse procedure begins at line 210.  It reads a record and
  84. arranges for appropriate processing.  Line 220 calls a routine to read
  85. the first portion of the next record.  This routine (beginning at line
  86. 370) sets RECORDTYPE% to the type of record and RECORDLENGTH% to the
  87. length of the remainder of the records.  If the record is one of the
  88. seven types listed in lines 240 through 300, control is passed to the
  89. appropriate routine (which will RETURN directly when through).  If the
  90. record is another type, the remaining bytes are read but ignored.  This
  91. is done with a routine (beginning at line 480) designed to get the next
  92. byte from the file.
  93.      The basic strategy for getting a byte from the files uses a
  94. pointer, indicating the position in BUFFER$ in which the desired byte
  95. is stored.  This is incremented by one after each byte is used.  If the
  96. resulting value exceeds 128, the next 128 characters are read into
  97. BUFFER$, and the pointer is reset to 1.
  98.      Lines 480 through 550 do the work.  The next byte is copied into
  99. BYTE$ as a character and the pointer is incremented so that it
  100. indicates the next character in BUFFER$.  If necessary, a new set of
  101. bytes is read into BUFFER$ and POINTER$ is reset.  Line 490 saves the
  102. previous byte for possible further processing.
  103.      As indicated earlier, each record starts with a header -- two
  104. bytes indicating the type of record, followed by two bytes indicating
  105. the length of the remainder of the record.  These values are to be
  106. stored in two variables: RECORDTYPE% and RECORDLENGTH%.  The requisite
  107. procedure begins at line 370.  In each case, two bytes are obtained
  108. (using the procedure at line 480).  They are combined to form a string
  109. (called PREVIOUSBYTE$+BYTE$) that then is converted to an integer value
  110. by the CVI function.
  111.      Processing the header (type 0) record is not strictly necessary.
  112. However, checking its validity is wise.  It also should be the first
  113. record on the file.  A valid header record has a length of two bytes.
  114. Version 1A writes an ASCII 4 in each one.  All three conditions are
  115. checked in the procedure that runs from line 1010 to 1100.
  116.      Date are stored in four types of records: integer value records
  117. (type 13), double-precision value records (type 14), character string
  118. records (type 15), and formula records (type 16).  One such record
  119. exists for each occupied cell in the worksheet.  No information is
  120. stored for empty cells.
  121.      Each data record includes information about location of the cell,
  122. including both row and column numbers.  These row and column numbers
  123. begin with zero; thus, row number 3 is displayed as row 4, column number
  124. 0 is displayed as column A, etc.  Cells are stored in order, beginning
  125. with the upper left portion of the worksheet, proceeding from left to
  126. right within rows and from the top row to the bottom.
  127.      When a portion of a worksheet is saved (for example, with a /File
  128. Extract Value instruction), cell locations are converted to those that
  129. would have been applicable if the portion had been in the upper left
  130. corner of the worksheet.  For ease of interpretation, a cell's location
  131. can be printed in "external" terms -- that is, as it would be
  132. displayed.  Lines 680-760 contain a procedure designed to show the
  133. location of a cell in ROW% and COLUMN%.
  134.      In each of the four types of data records -- 13, 14, 15, and 16 --
  135. the first byte indicates the format to be used when displaying the
  136. contents of the cell, and the next four bytes indicate the column and
  137. row numbers in which the cell is located.  The procedure between lines
  138. 570 and 660 processes the first five bytes of a data record.  After
  139. this has been run, the procedure beginning at line 680 can be used to
  140. print the row and column in "display" terms.
  141.      The simplest data record is type 13, which contains an integer
  142. value stored in two bytes.  The location and contents of such records
  143. are obtained and printed with the procedure between lines 1340 and 1410.
  144.      Numeric data not stored as two-byte integers are stored as eight-
  145. byte (double-precision) floating-point numbers, such as are present in
  146. records of type 14.
  147.      Unfortunately, double-precision numbers are stored in one format
  148. by 123 and in another by BASIC.  All double-precision numbers in
  149. worksheet files are stored in the format used by the Intel 8087
  150. coprocessor.  The eight bytes representing such values are stored
  151. "backwards" on the file.  To be used in BASIC programs, such values
  152. must be converted.  Some compilers for other languages (for example,
  153. Pascal and C) do not suffer from this drawback.
  154.      It is possible to call up an assembly-language routine designed to
  155. perform such a conversion from a BASIC program.  Although inelegant,
  156. this procedure to convert the double-precision value is used beginning
  157. at line 780.  Lines 790 through 810 test to see if the value is not
  158. available (displayed by 123 as NA).  In worksheet files such values are
  159. indicated by an ASCII 255 byte followed by an ASCII 240 byte.  The
  160. remaining bytes have values of zero but the first two suffice for
  161. purposes of identification.  Line 820 and 830 test for a zero value.
  162. This is indicated by zero values for all eight bytes, but inspection of
  163. the first two suffices.  The remainder of the procedure performs the
  164. conversion.
  165.      Double-precision value records are processed beginning at line
  166. 1430.  Lines 1460 through 1490 get the eight bytes containing the
  167. value, putting the numeric values of the bytes in vector BYT%.  The
  168. bytes are put in "backwards" -- the value of the first BYT%(8), the
  169. second in BYT%(7), etc.
  170.      When vectors BYT%(1) through BYT%(8) are ready, the conversion
  171. procedure is called.  The result is returned as DOUBLE# (a double-
  172. precision number), unless ISNA% equals 1 in which case the cell
  173. contains an NA.  Line 1510 prints either the value or NA.  
  174.      Character string records (type 15) are much simpler than double-
  175. precision value records.  The character string follows the cell format
  176. and location in the data record.  The first character of the string
  177. indicates the positioning for display purposes (an apostrophe for left
  178. justification, a quotation mark for right justification, a caret for
  179. centering, etc.).  The last character is an ASCII 0 (null).  The
  180. requisite procedure runs from line 1540 through line 1630.
  181.      Since five bytes are used for the record format, row, and column,
  182. the string is stored in the remaining (RECORDLENGTH%-5) bytes.  These
  183. are assembled into a CHARSTRING$, which is then printed.
  184.      Much of the power of 123 comes from its use of formulas, which
  185. indicate how the value in a cell is to be calculated.  A formula record
  186. (type 16) is used for any cell with such a formula.  Fortunately, the
  187. last calculated value of the formula (the number that is displayed) is
  188. also stored.
  189.      A formula record is, in effect, a double-precision value record
  190. plus a series of bytes containing a formula.  With some minor
  191. modifications, type 16 records therefore can be processed in a manner
  192. that is similar to that used for type 14 records.  A procedure to do
  193. this can be found in lines 1650 through 1780.
  194.      Lines 1660 through 1730 correspond to lines 1440 through 1510 in
  195. the procedure for double-precision values.  Lines 1740 through 1770
  196. take care of the formula information.  The format, cell location and
  197. last computed value require 13 bytes, so the formula is stored in the
  198. remaining (RECORDLENGTH%-13) bytes, which are simply read and ignored.
  199. If desired, this procedure could also be used for double-precision
  200. values, since type 14 records have a record length of 13, and the FOR
  201. loop in lines 1750-1770 will not execute in such cases.
  202.      When a worksheet (or portion of one) is saved, 123 writes a record
  203. indicating the range from which the data came.  The record (type 6)
  204. indicates the column and row at the upper left corner of the range in
  205. which data were contained.  Each value is stored as a two-byte integer.
  206.      For files saved with a /FS command, the "from" row and column are
  207. both zero, and the "to" row and column indicate the lower right corner
  208. of the area containing data.  For portions of files extracted with a
  209. /FX command, the values indicate the range that the area containing
  210. data occupied in the original worksheet.  Since cell locations are
  211. converted to a "base" of 0,0 when a portion of a worksheet is
  212. extracted, the "from" values must be subtracted from the "to" values
  213. for consistency.  The resulting locations are printed by lines
  214. 1290-1310.
  215.      The last record in a valid worksheet files if of type 1 and has a
  216. length of zero.  The procedure between lines 1800 and 1820 processes
  217. it.  The program to read and print the essential information from a
  218. worksheet file is now complete.  Incorporating these routines in other
  219. programs is relatively simple, making it possible to do any type of
  220. processing with a worksheet file.
  221.      To create a new worksheet file the process must be reversed.
  222. A valid header record must begin the new file, and a valid end-of-
  223. worksheet record must end it.  Including a range record after the
  224. header and before the data records is desirable (but not necessary).
  225. If possible, data records should be stored in order (left-to-right
  226. within rows, top-to-bottom by rows).
  227.      Files saved with 123 typically include a great deal of additional
  228. information.  To print the contents of the records containing such
  229. information, add these lines:
  230.  
  231. 305 PRINT"Record Type";RECORDTYPE%
  232. 335 PRINT ASC(BYTE$);
  233. 345 PRINT
  234.  
  235. These statements will print the type of each such record, followed by
  236. the numeric values of the bytes in it.
  237.